#pragma once
#include <assert.h>
#include <locale.h>
#include <time.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <windows.h>
#include "CH58x_common.h"
#include "simu_mcu582.h"
#include "zq_device.h"
#include "task_dbg.h"


typedef struct {
    uint8_t key[3];
    uint16_t adc[4];      // 0-3：NTC1，NTC2，VBAT，VREF

    uint32_t gpioa;       // 值; 每个bit表示一个IO
    uint32_t gpiob;       // 值; 每个bit表示一个IO
    uint32_t gpioa_d;     // 输入/输出; 每个bit表示一个IO, 1 表示输出
    uint32_t gpiob_d;     // 输入/输出; 每个bit表示一个IO
    //uint32_t gpioa_pu;    // 上拉输入; 每个bit表示一个IO
    //uint32_t gpiob_pu;    // 上拉输入; 每个bit表示一个IO
    //uint32_t gpioa_pd;    // 下拉输入; 每个bit表示一个IO
    //uint32_t gpiob_pd;    // 下拉输入; 每个bit表示一个IO
} SimuHWData;

typedef enum
{
    IWDG_PR_4 = 0, // 4分频
    IWDG_PR_8,     // 8分频
    IWDG_PR_16,    // 16分频
    IWDG_PR_32,    // 32分频
    IWDG_PR_64,    // 64分频
    IWDG_PR_128,   // 128分频
    IWDG_PR_256,   // 256分频
    IWDG_PR_512    // 512分频
} IWDG_32K_PR;

typedef enum
{
    KEY_UNPROTECT = 0x5555,        //解除保护
    KEY_RELOADING_COUNT = 0xAAAA,  //重装载计数值
    KEY_START_IWDG = 0xCCCC        //启动看门狗
} IWDG_KR_Key;

typedef enum
{
    /* 下面等级将使用高精度监控，210uA消耗 */
    HALevel_1V9 = 0, // 1.7-1.95
    HALevel_2V1,     // 1.9-2.15
    HALevel_2V3,     // 2.1-2.35
    HALevel_2V5,     // 2.3-2.55

    /* 下面等级将使用低功耗监控，1uA消耗 */
    LPLevel_1V7 = 0x80,
    LPLevel_1V8,
    LPLevel_1V9,
    LPLevel_2V0,
    LPLevel_2V1,
    LPLevel_2V2,
    LPLevel_2V3,
    LPLevel_2V4,

} VolM_LevelypeDef;

#define  RB_CLK_RC16M_PON   0x02                      // RWA, enable RC16M OSC HSI
#define  RB_CLK_XT32M_PON   0x04                      // RWA, enable XT32M OSC HSE
#define  RB_CLK_XT32M_KEEP  0x08                      // RWA, disable auto closing when in halt mode
#define  RB_CLK_PLL_PON     0x10                      // RWA, enable PLL power on

#define  RB_CLK_PLL_DIV     0x1F                      // RWA, output clock divider from PLL or CK32M
#define  RB_CLK_SYS_MOD     0xC0                      // RWA, system clock source mode: 00=divided from 16MHz/32MHz, 01=divided from PLL-624MHz, 10=directly from 16MHz/32MHz, 11=directly from 32KHz
#define  RB_XROM_SCLK_SEL   0x0100                    // RWA, XROM clk 624MHz selected
#define  RB_OSC32M_SEL      0x0200                    // RWA, PLL source clk external 32MHz selected
#define  RB_PLL_GATE_DISS   0x1000                    // RWA, PLL clk closed when source clk changed
#define  RB_PLL_GATE_TIME   0x2000                    // RWA, PLL clk time sel closed when source clk changed

#define CAB_LSIFQ       32768


extern HANDLE simu_main_h;  // 主任务线程句柄
extern HANDLE simu_mutex;   // 主任务线程互斥, 用来模拟器采样和主任务线程隔离


extern SimuHWData simu_hw;         // 模拟硬件数据, 由模拟器周期下发

extern void TMOS_SystemProcess(void);

extern void DllPrintf(char* fmt, ...);
extern void EEPROM_READ(uint32_t StartAddr, uint8_t* Buffer, int Length);
extern void EEPROM_ERASE(uint32_t StartAddr, int Length);
extern void EEPROM_WRITE(uint32_t StartAddr, uint8_t* Buffer, int Length);
extern void FLASH_ROM_READ(uint32_t StartAddr, uint8_t* Buffer, int Length);
extern void FLASH_ROM_ERASE(uint32_t StartAddr, int Length);
extern void FLASH_ROM_WRITE(uint32_t StartAddr, uint8_t* Buffer, int Length);

extern void SimuBuzzor(int isOn);

extern void SimuUartInit(uint8_t port, int baudrate, uint8_t* rx_buf, uint16_t rx_buf_size);
extern void SimuUartClose(uint8_t port);
extern void SimuUartSend(uint8_t port, uint8_t* buf, uint16_t len);
//extern void SimuUartRecv(uint8_t port, void (*rx_cb)(ZqCommPkg* pkg));
//extern void SimuC485Recv(void (*rx_cb)(ZqCommPkg* pkg));
extern void RTC_InitTime(uint16_t y, uint16_t mon, uint16_t d, uint16_t h, uint16_t m, uint16_t s);
extern void RTC_GetTime(uint16_t* py, uint16_t* pmon, uint16_t* pd, uint16_t* ph, uint16_t* pm, uint16_t* ps);
extern uint32_t RTC_GetCycle32k(void);
extern void HSECFG_Capacitance(HSECapTypeDef c);

typedef struct {
    char* uart_port_str;            // 串口名称字串
    HANDLE mutex;
    HANDLE uart;                    // 串口句柄
    HANDLE pipe_read;               // 用管道模拟串口 pipe read handle
    HANDLE pipe_write;              // 用管道模拟串口 pipe write handle
    HANDLE rx_thread;               // 通讯接收线程句柄
} ZqSimuUartHandle;
extern ZqSimuUartHandle zq_simu_uart_handle[4];


// some debug functions
extern long long SimuDbgGetSpanUs(bool start);